#!/usr/bin/env python
# -*- coding: utf-8 -*-
"""  
@Project : project
@File : ssh_val.py
@Author : 薄荷糖
@Time : 2025/9/9 18:57  
@脚本说明 : 
"""
import ipaddress
import threading
import paramiko
import warnings

warnings.filterwarnings("ignore")
warnings.simplefilter("ignore")


def run_ssh(host, port, users, passwds):
    """
    SSH弱口令扫描主函数
    :param host: 目标主机/IP段
    :param port: SSH端口
    :param users: 用户名列表
    :param passwds: 密码列表
    """
    print(f"[*] 开始扫描SSH弱口令: {host}:{port}")

    # 预处理用户名和密码
    users = [u.strip() for u in users if u.strip()]
    passwds = [p.strip() for p in passwds if p.strip()]

    if not users or not passwds:
        print(f"[-] 用户名或密码列表为空")
        return

    print(f"[*] 用户名: {len(users)} 个, 密码: {len(passwds)} 个")

    # 控制并发线程数量
    max_threads = 100
    semaphore = threading.Semaphore(max_threads)

    threads = []
    if '/' in host:
        # 网段扫描模式
        try:
            network = ipaddress.IPv4Network(host, strict=False)
            print(f"[*] 扫描网段: {network}")

            for ip in network.hosts():
                ip_str = str(ip)
                for user in users:
                    for passwd in passwds:
                        t = threading.Thread(
                            target=ssh_connect,
                            args=(ip_str, port, user, passwd, semaphore)
                        )
                        t.start()
                        threads.append(t)
        except ValueError:
            print(f"[-] 无效的网段格式: {host}")
            return
    else:
        # 单IP扫描模式
        for user in users:
            for passwd in passwds:
                t = threading.Thread(
                    target=ssh_connect,
                    args=(host, port, user, passwd, semaphore)
                )
                t.start()
                threads.append(t)

    # 等待所有线程完成
    for t in threads:
        t.join()

    print(f"[*] SSH弱口令扫描完成")


def ssh_connect(host, port, username, password, semaphore):
    """
    SSH连接测试函数
    """
    semaphore.acquire()
    try:
        ssh = paramiko.SSHClient()
        ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())

        # 优化超时设置
        ssh.connect(
            host,
            port=port,
            username=username,
            password=password,
            timeout=5,
            banner_timeout=10,
            auth_timeout=5
        )

        if ssh.get_transport().is_active():
            stdin, stdout, stderr = ssh.exec_command("echo lyf", timeout=3)
            output = stdout.read().decode('utf-8').strip()

            if "lyf" in output:
                print(f"[+] {host}:{port} SSH存在弱口令 [{username}/{password}]")

    except paramiko.AuthenticationException:
        pass  # 认证失败是正常情况
    except Exception:
        pass  # 静默处理所有其他异常
    finally:
        try:
            ssh.close()
        except:
            pass
        semaphore.release()

